
package StackAlgorithm;

/**
 *
 * @author hazem
 */
public class firstAlgorithm
{
	char[][][] map;
	Tile startingTile;
	Tile currentTile = startingTile;
	Tile bomb;
	Tile victim;
	PathStack path = new PathStack();

	// -------------------------------------------------------------------------------------------------------------------------------------
	public firstAlgorithm(char[][][] m, Tile start, Tile b, Tile v)
	{

		map = m;
		startingTile = start;
		bomb = b;
		victim = v;

	}

	// ---------------------------------------------------------------------------------------------------------------------------------------

	public String findThePath()
	{
		while (!currentTile.compareTiles(victim)
				&& !currentTile.compareTiles(bomb) && !path.isEmpty())
		{
			if ((currentTile.column - 1) >= 0
					&& map[currentTile.level][currentTile.row][currentTile.column - 1] != 'x'
					&& map[currentTile.level][currentTile.row][currentTile.column - 1] != 'v')
			{
				map[currentTile.level][currentTile.row][currentTile.column - 1] = 'v';
				currentTile.setColumn(currentTile.column-1);
				path.push(currentTile);
			} else if (currentTile.row - 1 >= 0
					&& currentTile.column - 1 >= 0
					&& map[currentTile.level][currentTile.row - 1][currentTile.column - 1] != 'x'
					&& map[currentTile.level][currentTile.row - 1][currentTile.column - 1] != 'v')
			{
				map[currentTile.level][currentTile.row - 1][currentTile.column - 1] = 'v';
				currentTile.setRow(currentTile.row-1);
				currentTile.setColumn(currentTile.column-1);
				path.push(currentTile);
			} else if (currentTile.row - 1 >= 0
					&& map[currentTile.level][currentTile.row - 1][currentTile.column] != 'x'
					&& map[currentTile.level][currentTile.row - 1][currentTile.column] != 'v')
			{
				map[currentTile.level][currentTile.row - 1][currentTile.column] = 'v';
				currentTile.setTile(currentTile.level, currentTile.row - 1,
						currentTile.column);
				path.push(currentTile);
			} else if (currentTile.row - 1 >= 0
					&& currentTile.column + 1 < map[currentTile.level].length
					&& map[currentTile.level][currentTile.row - 1][currentTile.column + 1] != 'x'
					|| map[currentTile.level][currentTile.row - 1][currentTile.column + 1] != 'v')
			{
				map[currentTile.level][currentTile.row - 1][currentTile.column + 1] = 'v';
				currentTile.setTile(currentTile.level, currentTile.row - 1,
						currentTile.column + 1);
				path.push(currentTile);
			} else if (currentTile.column + 1 < map[currentTile.level].length
					&& map[currentTile.level][currentTile.row][currentTile.column + 1] != 'x'
					|| map[currentTile.level][currentTile.row][currentTile.column + 1] != 'v')
			{
				map[currentTile.level][currentTile.row][currentTile.column + 1] = 'v';
				currentTile.setTile(currentTile.level, currentTile.row,
						currentTile.column + 1);
				path.push(currentTile);
			} else if (currentTile.column + 1 < map[currentTile.level].length
					&& currentTile.row + 1 < map[currentTile.level].length
					&& map[currentTile.level][currentTile.row + 1][currentTile.column + 1] != 'x'
					|| map[currentTile.level][currentTile.row + 1][currentTile.column + 1] != 'v')
			{
				map[currentTile.level][currentTile.row + 1][currentTile.column + 1] = 'v';
				currentTile.setTile(currentTile.level, currentTile.row + 1,
						currentTile.column + 1);
				path.push(currentTile);
			} else if (currentTile.row + 1 < map[currentTile.level].length
					&& map[currentTile.level][currentTile.row + 1][currentTile.column] != 'x'
					|| map[currentTile.level][currentTile.row + 1][currentTile.column] != 'v')
			{
				map[currentTile.level][currentTile.row + 1][currentTile.column] = 'v';
				currentTile.setTile(currentTile.level, currentTile.row + 1,
						currentTile.column);
				path.push(currentTile);
			} else if (currentTile.row + 1 < map[currentTile.level].length
					&& currentTile.column - 1 <= 0
					&& map[currentTile.level][currentTile.row + 1][currentTile.column - 1] != 'x'
					|| map[currentTile.level][currentTile.row + 1][currentTile.column - 1] != 'v')
			{
				map[currentTile.level][currentTile.row + 1][currentTile.column - 1] = 'v';
				currentTile.setTile(currentTile.level, currentTile.row + 1,
						currentTile.column - 1);
				path.push(currentTile);

			} else if (map[currentTile.level][currentTile.row][currentTile.column] >= '0'
					&& map[currentTile.level][currentTile.row][currentTile.column] <= '9')
			{
				currentTile = findTile(
						currentTile.level,
						map[currentTile.level][currentTile.row][currentTile.column]);
				map[currentTile.level][currentTile.row][currentTile.column] = 'v';
				path.push(currentTile);

			} else
			{
				path.pop();
				currentTile = (Tile) path.peek();
			}

		}
		return writeThePath();

	}

	// ---------------------------------------------------------------------------------------------------------------------------------------------
	public Tile findTile(int currentLevel, int nextLevel)
	{
		String s = "" + currentLevel;
		for (int i = 0; i < map[nextLevel].length; i++)
			for (int j = 0; j < map[nextLevel].length; j++)
			{
				if (map[nextLevel][i][j] == s.charAt(0))
					return new Tile(nextLevel, i, j);
			}
		return null;

	}

	// ----------------------------------------------------------------------------------------------------------------------------------------------
	public char determineDirection(Tile firstTile, Tile secondTile)
	{
		String s = "";
		if (firstTile.level == secondTile.level)
		{
			if (secondTile.column - firstTile.column == 1
					&& secondTile.row - firstTile.row == 1)
				return 'i';
			else if (firstTile.column - secondTile.column == 1
					&& secondTile.row - firstTile.row == 1)
				return 'h';
			else if (firstTile.column - secondTile.column == 1
					&& secondTile.row - secondTile.column == 1)
				return 'j';
			else if (secondTile.column - firstTile.column == 1
					&& firstTile.row - secondTile.row == 1)
				return 'k';
			else if (secondTile.column - firstTile.column == 1)
				return 'e';
			else if (secondTile.row - firstTile.row == 1)
				return 'n';
			else if (firstTile.column - secondTile.column == 1)
				return 'w';
			else if (firstTile.row - secondTile.row == 1)
				return 's';
		} else if (firstTile.level != secondTile.level)
		{
			s += firstTile;
			return s.charAt(0);
		}
		return ' ';

	}

	// ----------------------------------------------------------------------------------------------------------------------------------------------
	public String writeThePath()
	{
		String sequence = "";
		Tile tempTile = (Tile) path.pop();

		while (!path.isEmpty())
		{
			sequence += determineDirection(tempTile, (Tile) path.peek());
			tempTile = (Tile) path.pop();
		}
		return sequence;
	}

}
